#include "TcpServer.hpp"
#include "Daemom.hpp"
#include "Protocol.hpp"

using namespace FangZhang_Server;

// 服务端用法
void Usage(const char* flieName)
{
    std::cout << "Usage:\n" << flieName << " port" << std::endl;
}

//         /*测试代码*/
// void print(int sock)
// {
//     while(1)
//     {
//         std::cout << "sock" << std::endl;
//         sleep(1);
//     }
// }


static Response Calculate(const Request& req)
{
    Response res;
    switch(req._op)
    {
    case '+':
        res._result = req._x + req._y;
        break;

    case '-':
        res._result = req._x - req._y;
        break;

    case '*':
        res._result = req._x * req._y;
        break;

    case '/':
        if(req._y == 0) 
            res._code = 1; // 不能除零
        else 
            res._result = req._x / req._y;
        break;

    case '%':
        if(req._y == 0) 
            res._code = 2; // 不能模零
        else 
            res._result = req._x % req._y;
        break;

    default:
        res._code = 3;//运算符不在范围内
        break;
    }

    return res;
}

void Calculator(int sock)
{
    std::string inBuff;
    while(1)
    {
        // 服务端先接收字符串
        int ret = Recv(sock, inBuff);
        if(!ret) break; // 对端关闭连接

        // 接受到请求后进行Decode
        std::string str = Decode(inBuff);
        if(str.empty()) continue; // 没有足够的正文就继续回去读数据
        
        // 有正文就继续反序列化并发送

        // str反序列化并填充Request对象
        Request req;
        req.DeserializeRequest(str);

        // 计算结果并填充Response对象
        Response res = Calculate(req);

        // 将Response对象序列化
        std::string echo = res.SerializeResponse();
        echo = Encode(echo);

        // 结果传给客户端
        Send(sock, echo);
    }
}


int main(int argc, char* argv[])
{
    // 固定格式 文件名 + port
    if(argc != 2)
    {
        Usage(argv[0]);
        exit(1);
    }

    MyDaemon();
    std::cout << "hello" << std::endl;
    // 初始化时就直接前三步走完
    Server server(atoi(argv[1]));

    //这里添加任务
    server.AddService(Calculator);

        /*测试*/
    //server.AddService(print);
    
    // 这里进行通信
    server.StartServer();

    return 0;
}
